using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;

namespace DatabaseManager.Util.Exporters
{
    class DataExportCsv : DataExportBase
    {
        private char _seperator = ',';

        public override event DataExportProcessHandler DataExportProcess;

        public DataExportCsv(DataTable dataTable, string fileName, char separator)
            : base(dataTable, fileName) 
        {
            _seperator = separator;
        }

        public DataExportCsv(DataTable dataTable, string fileName)
            : base(dataTable, fileName) { }

        public override void Export()
        {
            int currentDataRowIndex = 0;
            int dataRowIndexCount = _dataTable.Rows.Count;

            StreamWriter streamWriter = new StreamWriter(_fileName);

            //Write columns
            for (int i = 0; i < _dataTable.Columns.Count; i++)
            {
                DataColumn dataColumn = _dataTable.Columns[i];

                streamWriter.Write(EscapeCsvField(dataColumn.ColumnName.ToString(), _seperator));

                if (i < _dataTable.Columns.Count - 1)
                {
                    streamWriter.Write(_seperator);
                }
            }

            streamWriter.WriteLine();

            //Write data
            foreach (DataRow dataRow in _dataTable.Rows)
            {
                currentDataRowIndex++;

                object[] values = dataRow.ItemArray;

                for (int j = 0; j < values.Length; j++)
                {
                    string value = ObjectToString(values[j]);

                    streamWriter.Write(EscapeCsvField(value, _seperator));

                    if (j < _dataTable.Columns.Count - 1)
                    {
                        streamWriter.Write(_seperator);
                    }
                }

                streamWriter.WriteLine();

                if (DataExportProcess != null)
                {
                    DataExportProcess(
                        this,
                        new DataExportProcessEventArgs(currentDataRowIndex, dataRowIndexCount));
                }
            }

            streamWriter.Close();
        }

        public char Separator
        {
            get { return _seperator; }
            set { _seperator = value; }
        }

        private string EscapeCsvField(string value, char separator)
        {
            bool useQuotes = false;

            //Checks for a line feed and carriage return
            if (value.Contains("\r") || value.Contains("\n"))
                useQuotes = true;
            
            //Checks for the separator charactor
            if (value.Contains(separator.ToString()))
                useQuotes = true;

            //Checks for leading or trailing spaces
            if (value.StartsWith(" ") || value.EndsWith(" "))
                useQuotes = true;

            if (useQuotes)
            {
                //escape the field value an return it
                return "\"" + value.Replace("\"", "\"\"") + "\"";
            }
            else
            {
                //return the unescaped source value
                return value;
            }
        }
    }
}
